import glob
import os
import tkinter as tk
from tkinter import messagebox
from PIL import Image, ImageTk, ImageDraw
import keyboard
import math
from tkinter import ttk

def create_window(parent=None):
    # 创建窗口
    if parent is None:
        root = tk.Tk()
    else:
        root = tk.Toplevel(parent)
    # 创建窗口
    root.title("序列帧图片裁剪器鼠标移动")
    root.config(bg="grey")
    root.geometry("1000x1000+0+0")
    global offX, offY,center_x,center_y,canvas_width,canvas_height
    offX = 60
    offY = 50
    center_x = 0
    center_y = 0
    canvas_width = 800
    canvas_height = 800
    center_x = canvas_width / 2
    center_y = canvas_height / 2

    # 裁剪图片边界区域
    global left_value, right_value, up_value, down_value
    left_value = 1
    right_value = 1
    up_value = 1
    down_value = 1

    def find_png_files(directory):
        png_files = glob.glob(os.path.join(directory, '**', '*.png'), recursive=True)
        return png_files



    global imgs_scale, scale_value, scale_index
    scale_value = 1
    imgs_scale = []
    scale_index = 0

    # 裁剪图片路径输入框
    entry_scale_change_path = tk.StringVar()
    entry_path = tk.Entry(root, textvariable=entry_scale_change_path)
    entry_path.place(x=offX + 40, y=offY - 37)

    # 图像绘制位置坐标
    canvas_scale = tk.Canvas(root, width=800, height=800, bg="gray")
    canvas_scale.place(x=offX + 70, y=offY + 100)
    drag_data = {"x": 0, "y": 0, " dragging": False}
    # 创建滚动条
    # scrollbar_v = ttk.Scrollbar(root, orient="vertical", command=canvas_scale.yview)
    # scrollbar_h = ttk.Scrollbar(root, orient="horizontal", command=canvas_scale.xview)
    # scrollbar_v.place(x=offX + 70 + 800, y=offY + 100, height=800)
    # scrollbar_h.place(x=offX + 70, y=offY + 900, width=817)

    # 配置 Canvas 滚动
    #canvas_scale.configure(yscrollcommand=scrollbar_v.set, xscrollcommand=scrollbar_h.set)
    #canvas_scale.configure(scrollregion=(0, 0, 2048, 2048))  # 设置滚动区域大小（根据图片大小调整）

    def on_scroll(*args):
        canvas_scale.update_idletasks()
        visible_area = canvas_scale.bbox("visible")
        # 只绘制 visible_area 内的图像或图形
    # 鼠标事件处理
    def on_mouse_press(event):
        # global left_value, right_value, up_value, down_value
        # dx = event.x - drag_data["x"]
        # dy = event.y - drag_data["y"]
        #
        # # 更新矩形边界值
        # left_value += dx
        # right_value += dx
        # up_value += dy
        # down_value += dy

        drag_data["x"] = event.x
        drag_data["y"] = event.y
        drag_data["dragging"] = True


    def on_mouse_release(event):
        drag_data["dragging"] = False

    def on_mouse_move(event):
        global left_value, right_value, up_value, down_value
        if drag_data["dragging"]:
            dx = event.x - drag_data["x"]
            dy = event.y - drag_data["y"]

            # 更新矩形边界值
            left_value += dx
            right_value += dx
            up_value += dy
            down_value += dy

            # 更新 drag_data 以实现连续拖动
            drag_data["x"] = event.x
            drag_data["y"] = event.y


    canvas_scale.bind("<ButtonPress-1>", on_mouse_press)
    canvas_scale.bind("<ButtonRelease-1>", on_mouse_release)
    canvas_scale.bind("<B1-Motion>", on_mouse_move)

    def load_images():
        global imgs_scale, button_scale
        global button_scale_load, button_scale_sure, scale_value, input_folder, output_folder, imgs_scale_path
        imgs_scale_path = []
        input_folder = entry_scale_change_path.get()
        # output_folder = input_folder + "\\output"#r"D:\Users\admin\Desktop\File\130001\output"

        # if not os.path.exists(output_folder):
        #     os.makedirs(output_folder)

        for filename in os.listdir(input_folder):
            if filename.endswith('.png') or filename.endswith('.jpg'):
                imgs_scale_path.append(
                    os.path.join(input_folder, filename))  # = [Image.open(os.path.join(input_folder, filename))]

        imgs_scale = [Image.open(path) for path in imgs_scale_path]
        update_frame_sclae()

    # 预览输入框
    entry_scale_change = tk.StringVar()
    entry_path = tk.Entry(root, textvariable=entry_scale_change, width=5)
    entry_path.place(x=offX + 300, y=offY - 37)

    def get_scale_value():
        global scale_value
        scale_value = 0
        scale_value = float(entry_scale_change.get())
        # update_frame_sclae()

    button_scale_sure = tk.Button(root, text="缩放大小预览", command=get_scale_value, bg='skyblue').place(x=offX + 350,
                                                                                                          y=offY - 40)
    button_scale = tk.Button(root, text="加载图片", command=load_images, bg='skyblue').place(x=offX + 200, y=offY - 40)

    def get_tailor_value():
        global button_tailor_left, button_tailor_right, button_tailor_up, button_tailor_down, imgs_scale
        global left_value, right_value, up_value, down_value, resized_img
        # if (entry_tailor_left.get() != ""):
        #     left_value = int(entry_tailor_left.get())
        # if (entry_tailor_right.get() != ""):
        #     right_value = - int(entry_tailor_right.get())
        # else:
        #     right_value = imgs_scale[0].width
        # if (entry_tailor_up.get() != ""):
        #     up_value = int(entry_tailor_up.get())
        # if (entry_tailor_down.get() != ""):
        #     down_value = - int(entry_tailor_down.get())
        # else:
        #     down_value = imgs_scale[0].height

        left_value = 0
        up_value = 0
        right_value = int(entry_tailor_left.get())
        down_value = int(entry_tailor_right.get())
        # update_frame_sclae()

    # 裁剪left输入框
    entry_tailor_left = tk.StringVar()
    entry_path = tk.Entry(root, textvariable=entry_tailor_left, width=5)
    entry_path.place(x=offX + 50, y=offY + 60)
    # button_tailor_left = tk.Button(root, text="确认",command=get_tailor_value).place(x=offX + 990, y=offY + 57)
    tk.Label(root, text="宽度", bg="green").place(x=offX + 50, y=offY + 30)

    # 裁剪right输入框
    entry_tailor_right = tk.StringVar()
    entry_path = tk.Entry(root, textvariable=entry_tailor_right, width=5)
    entry_path.place(x=offX + 100, y=offY + 60)
    # button_tailor_right = tk.Button(root, text="确认",command=get_tailor_value).place(x=offX + 1090, y=offY + 57)
    tk.Label(root, text="高度", bg="green").place(x=offX + 100, y=offY + 30)

    # # 裁剪up输入框
    # entry_tailor_up = tk.StringVar()
    # entry_path = tk.Entry(root, textvariable=entry_tailor_up, width=5)
    # entry_path.place(x=offX + 150, y=offY + 60)
    # # button_tailor_up = tk.Button(root, text="确认",command=get_tailor_value).place(x=offX + 1190, y=offY + 57)
    # tk.Label(root, text="上边界", bg="green").place(x=offX + 150, y=offY + 30)
    #
    # # 裁剪down输入框
    # entry_tailor_down = tk.StringVar()
    # entry_path = tk.Entry(root, textvariable=entry_tailor_down, width=5)
    # entry_path.place(x=offX + 200, y=offY + 60)
    button_tailor_down = tk.Button(root, text="裁剪区域预览", command=get_tailor_value).place(x=offX + 290, y=offY + 57)
    #tk.Label(root, text="下边界", bg="green").place(x=offX + 200, y=offY + 30)

    def left_right():
        global left_value, right_value

        dx = center_x

        # 更新矩形边界值
        left_value = dx-int(entry_tailor_left.get())/2
        right_value = dx+int(entry_tailor_left.get())/2


    def up_down():
        global up_value, down_value

        dy = center_y

        # 更新矩形边界值
        up_value = dy - int(entry_tailor_right.get()) / 2
        down_value = dy + int(entry_tailor_right.get()) / 2

    tk.Button(root, text="左右对齐", command=left_right).place(x=offX + 450, y=offY +24)
    tk.Button(root, text="上下对齐", command=up_down).place(x=offX + 450, y=offY +57)

    check_var = tk.IntVar()
    tk.Label(root, text="勾选显示十字线", bg='green').place(x=offX + 290, y=offY +30)
    tk.Checkbutton(root, variable=check_var).place(x=offX + 390, y=offY +24)


    def check_status():
        if check_var.get():
            return 'on'
        else:
            return 'off'

    # 裁剪图片指定边界
    def tailor():
        global left_value, right_value, up_value, down_value, resized_img, imgs_scale, img

        finally_Names = input_folder.split("\\")
        finally_Name = finally_Names[len(finally_Names) - 1]
        output_folder = input_folder + "(new)"  # r"D:\Users\admin\Desktop\File\130001\output"
        if not os.path.exists(output_folder):
            os.makedirs(output_folder)

        for img in imgs_scale:
            name = img.filename.split("\\")[len(img.filename.split("\\")) - 1]

            img_crop = img.crop((left_value-(center_x-photo.width() / 2), up_value-(center_y-photo.height()/ 2)
                                 , right_value-(center_x-photo.width() / 2), down_value-(center_y-photo.height() / 2)))
            img_crop.save(os.path.join(output_folder, name))

    button_tailor = tk.Button(root, text="保存图片", command=tailor, bg="skyblue").place(x=offX + 480, y=offY - 40)

    # 刷新帧率图片
    def update_frame_sclae():
        global imgs_scale, scale_index, photo, resized_img, name, root_after2
        if imgs_scale:
            canvas_scale.delete("all")
            length = len(imgs_scale)
            img_scale = imgs_scale[scale_index]
            name = img_scale.filename.split("\\")[len(img_scale.filename.split("\\")) - 1]
            resize = [math.ceil(img_scale.size[0] * scale_value), math.ceil(img_scale.size[1] * scale_value)]
            resized_img = img_scale.resize(resize, Image.Resampling.LANCZOS)
            photo = ImageTk.PhotoImage(resized_img)
            x = int(photo.width() / 2)
            y = int(photo.height() / 2)

            canvas_scale.create_rectangle(center_x - photo.width() / 2, center_y - photo.height() / 2,
                                          center_x + photo.width() / 2,
                                          center_y + photo.height() / 2, fill="white", outline="black")
            canvas_scale.create_image(center_x, center_y, anchor=tk.CENTER, image=photo)

            canvas_scale.create_rectangle(left_value, up_value, right_value, down_value, outline="red")

            if check_status() == 'on':
                canvas_scale.create_line(0, center_y, canvas_width, center_y, fill="red", width=1)
                canvas_scale.create_line(center_x, 0, center_x, canvas_height, fill="red", width=1)

            scale_index = (scale_index + 1) % length  # 循环显示
        root_after2 = root.after(200, update_frame_sclae)

    root.mainloop()

if __name__ == "__main__":
    create_window(None)

